package com.mango.iot.gateway.coap.utils;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.TimeZone;

public class JacksonUtil {

    private static final Logger logger = LoggerFactory.getLogger(JacksonUtil.class);

    private static ObjectMapper jacksonMapper = new ObjectMapper();

    static {
        // 注册反序列化
        jacksonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注册序列化
        jacksonMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        DefaultSerializerProvider.Impl sp = new DefaultSerializerProvider.Impl();
        jacksonMapper.setSerializerProvider(sp);
        sp.setNullValueSerializer(new NullSerializer());
        // 时间输出为时间戳
        jacksonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
        jacksonMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    }

    static class NullSerializer extends JsonSerializer<Object> {
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeNull();
        }
    }

    public static ObjectMapper getObjectMapper() {
        return jacksonMapper;
    }

    public static <T> String obj2Json(T obj) {
        try {
            return jacksonMapper.writeValueAsString(obj);
        } catch (IOException e) {
            logger.error("obj 2 json error", e);
        }
        return null;
    }

    public static <T> T json2Obj(String json, Class<T> type) {
        try {
            return jacksonMapper.readValue(json, type);
        } catch (IOException e) {
            logger.error("json 2 obj error", e);
        }
        return null;
    }

    public static <T> List<T> json2List(String json, Class<T> type) {
        try {
            return jacksonMapper.readValue(json, getCollectionType(List.class, type));
        } catch (Exception e) {
            logger.error("json 2 list error", e);
        }
        return null;
    }

    private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return jacksonMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

}
